import React, { useState, forwardRef } from 'react';
import { 
  Box, 
  Typography, 
  Grid, 
  CircularProgress, 
  Card, 
  CardContent,
  Divider,
  Alert,
  Button,
  Dialog,
  DialogTitle,
  DialogContent,
  DialogActions,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableRow,
  Paper,
  IconButton,
  Slide
} from '@mui/material';
import KeyboardArrowLeftIcon from '@mui/icons-material/KeyboardArrowLeft';
import KeyboardArrowRightIcon from '@mui/icons-material/KeyboardArrowRight';
import CloseIcon from '@mui/icons-material/Close';
import AddIcon from '@mui/icons-material/Add';
import { useAuth } from 'contexts/AuthContext';
import { useQuery } from 'react-query';
import { CustomerCards, Customer } from 'api/queries';
import { useTranslation } from 'react-i18next';
import { CardButton } from 'components/atoms/ReusableButton';

/**
 * PaymentMethodsUserInterface - Unified component for payment methods management
 * 
 * This component can:
 * 1. Display a list of payment methods
 * 2. Set a payment method as default
 * 3. Remove a payment method
 * 
 * @param {Object} props
 * @param {string} props.cardId - Optional card ID for specific card actions
 * @param {string} props.actionType - Optional action type: 'view', 'setDefault', 'remove'
 * @param {string} props.title - Optional custom title
 * @param {string} props.description - Optional custom description
 * @param {boolean} props.showAddCardButton - Whether to show the add card button
 * @param {boolean} props.initiallyExpanded - Whether to show the UI initially or just the button
 * @param {string} props.buttonText - Optional custom button text to override translation
 * @param {boolean} props.simpleButton - If true, renders just the button without any wrappers (default: false)
 * 
 * @example
 * // Basic usage - shows button that reveals payment methods list
 * <PaymentMethodsUserInterface />
 * 
 * @example
 * // Set default card interface
 * <PaymentMethodsUserInterface 
 *   cardId="card_123456"
 *   actionType="setDefault"
 *   initiallyExpanded={false}
 * />
 * 
 * @example
 * // Simple button with custom text
 * <PaymentMethodsUserInterface
 *   buttonText="Manage Cards"
 *   simpleButton={true}
 * />
 */
const PaymentMethodsUserInterface = ({ 
  cardId,
  actionType = 'view',
  title,
  description,
  showAddCardButton = true,
  initiallyExpanded = false,
  buttonText,
  simpleButton = false
}) => {
  const { user } = useAuth();
  const { t } = useTranslation();
  const [dialogOpen, setDialogOpen] = useState(initiallyExpanded);
  const [actionState, setActionState] = useState(null);
  const [cards, setCards] = useState([]);
  const [activeCardIndex, setActiveCardIndex] = useState(0);
  // State for slide animations
  const [slideIn, setSlideIn] = useState(true);
  // eslint-disable-next-line
  const [slideDirection, setSlideDirection] = useState('left');
  const [confirmDialogOpen, setConfirmDialogOpen] = useState(false);
  const [confirmAction, setConfirmAction] = useState(null);
  //const theme = useTheme();
  
  // Transition component for main Dialog
  const DialogTransition = forwardRef(function Transition(props, ref) {
    return <Slide direction="up" ref={ref} {...props} />;
  });
  
  // Transition component for card slides
  // eslint-disable-next-line
  const CardTransition = forwardRef(function Transition(props, ref) {
    return <Slide direction={slideDirection} ref={ref} {...props} />;
  });

  // Get default card ID
  const customerQuery = useQuery(
    ["Customer", user?.accountId],
    Customer,
    { 
      retry: false,
      enabled: !!user?.accountId && dialogOpen,
      onSuccess: (data) => {
        if (data?.data?.invoice_settings?.default_payment_method) {
          const defId = data.data.invoice_settings.default_payment_method;
          const defaultCardId = typeof defId === 'object' ? defId.id : defId;
          if (cardId === defaultCardId && actionType === 'setDefault') {
            // Auto-show confirm dialog for requested card action
            setConfirmAction({
              type: 'setDefault',
              cardId: defaultCardId,
              isDefault: true
            });
            setConfirmDialogOpen(true);
          }
        }
      }
    }
  );

  // Get all cards
  const cardsQuery = useQuery(
    ["CustomerCards", user?.accountId],
    CustomerCards,
    { 
      retry: false,
      enabled: !!user?.accountId && dialogOpen,
      onSuccess: (data) => {
        const allCards = data?.data || [];
        setCards(allCards);
        
        // If cardId is provided, set active card index
        if (cardId) {
          const index = allCards.findIndex(c => c.id === cardId);
          if (index !== -1) {
            setActiveCardIndex(index);
            
            // Auto-show confirm dialog for requested card action
            if (actionType === 'remove') {
              const isDefault = customerQuery.data?.data?.invoice_settings?.default_payment_method === cardId;
              const hasMultipleCards = allCards.length > 1;
              
              setConfirmAction({
                type: 'remove',
                cardId: cardId,
                isDefault: isDefault,
                hasMultipleCards: hasMultipleCards
              });
              setConfirmDialogOpen(true);
            }
          }
        }
      }
    }
  );

  // Loading state
  const isLoading = customerQuery.isLoading || cardsQuery.isLoading;
  const hasError = customerQuery.isError || cardsQuery.isError;
  const hasMultipleCards = cards.length > 1;

  // Check if card is default
  const isDefaultCard = (cardId) => {
    if (!customerQuery.data?.data?.invoice_settings?.default_payment_method) return false;
    
    const defId = customerQuery.data.data.invoice_settings.default_payment_method;
    const defaultCardId = typeof defId === 'object' ? defId.id : defId;
    return cardId === defaultCardId;
  };

  // Handler for action state changes
  const handleActionStateChange = (state) => {
    setActionState(state);
    
    // Close dialog on success
    if (state.success) {
      setConfirmDialogOpen(false);
    }
    
    // Automatically reset state after 3 seconds
    setTimeout(() => {
      setActionState(null);
    }, 3000);
  };

  // Open main dialog
  const openDialog = () => {
    setDialogOpen(true);
    return { message: t("common.loadingCardDetails") };
  };

  // Close main dialog
  const closeDialog = () => {
    setDialogOpen(false);
    setActionState(null);
  };
  
  // Open confirmation dialog
  const openConfirmDialog = (action, cardId) => {
    const isDefault = isDefaultCard(cardId);
    
    setConfirmAction({
      type: action,
      cardId: cardId,
      isDefault: isDefault,
      hasMultipleCards: hasMultipleCards
    });
    
    setConfirmDialogOpen(true);
  };
  
  // Close confirmation dialog
  const closeConfirmDialog = () => {
    setConfirmDialogOpen(false);
    setActionState(null);
  };
  
  // Navigate to next card with smooth transition
  const nextCard = () => {
    if (!slideIn) return; // Prevent rapid clicks during transition
    setSlideIn(false);
    setActiveCardIndex((prevIndex) => (prevIndex + 1) % cards.length);
  };
  
  // Navigate to previous card with smooth transition
  const prevCard = () => {
    if (!slideIn) return; // Prevent rapid clicks during transition
    setSlideIn(false);
    setActiveCardIndex((prevIndex) => prevIndex === 0 ? cards.length - 1 : prevIndex - 1);
  };
  
  // Get current active card
  // eslint-disable-next-line
  const getCurrentCard = () => {
    if (!cards.length || activeCardIndex >= cards.length) return null;
    return cards[activeCardIndex];
  };

  // Render confirmation dialog
  const renderConfirmDialog = () => {
    if (!confirmAction) return null;
    
    const { type, cardId, isDefault, hasMultipleCards } = confirmAction;
    const card = cards.find(c => c.id === cardId);
    if (!card) return null;
    
    const isActionDisabled = 
      (type === 'remove' && isDefault && !hasMultipleCards) || 
      (type === 'setDefault' && isDefault);
    
    const dialogTitle = type === 'remove' 
      ? t("cardActions.removeCard") 
      : t("cardActions.setDefaultCard");
    
    const confirmText = type === 'remove' 
      ? t("cardActions.removeCardConfirmText") 
      : t("cardActions.setDefaultCardConfirmText");
    
    const buttonText = type === 'remove' 
      ? t("cardActions.confirmRemove") 
      : t("cardActions.confirmSetDefault");
    
    return (
      <Dialog 
        open={confirmDialogOpen} 
        onClose={closeConfirmDialog}
        fullWidth
        maxWidth="xs"
      >
        <DialogTitle>
          {dialogTitle}
          <IconButton
            aria-label="close"
            onClick={closeConfirmDialog}
            sx={{
              position: 'absolute',
              right: 8,
              top: 8,
            }}
          >
            <CloseIcon />
          </IconButton>
        </DialogTitle>
        <DialogContent>
          <TableContainer component={Paper} variant="outlined" sx={{ mb: 2 }}>
            <Table size="small">
              <TableBody>
                <TableRow>
                  <TableCell component="th" scope="row" sx={{ width: '40%' }}>
                    {t("paymentMethods.cardType")}
                  </TableCell>
                  <TableCell>{card.card.brand}</TableCell>
                </TableRow>
                <TableRow>
                  <TableCell component="th" scope="row">
                    {t("paymentMethods.cardNumber")}
                  </TableCell>
                  <TableCell>•••• {card.card.last4}</TableCell>
                </TableRow>
                <TableRow>
                  <TableCell component="th" scope="row">
                    {t("paymentMethods.expiryDate")}
                  </TableCell>
                  <TableCell>{card.card.exp_month}/{card.card.exp_year}</TableCell>
                </TableRow>
              </TableBody>
            </Table>
          </TableContainer>
          
          {isActionDisabled && type === 'remove' && (
            <Alert severity="warning" sx={{ mb: 2 }}>
              {t("cardActions.cannotRemoveDefaultCard")}
            </Alert>
          )}
          
          {isActionDisabled && type === 'setDefault' && (
            <Alert severity="info" sx={{ mb: 2 }}>
              {t("cardActions.alreadyDefaultCard")}
            </Alert>
          )}
          
          {actionState && actionState.error && (
            <Alert severity="error" sx={{ mb: 2 }}>
              {actionState.error.message || t("common.actionFailed")}
            </Alert>
          )}
          
          {actionState && actionState.success && (
            <Alert severity="success" sx={{ mb: 2 }}>
              {actionState.result?.message || t("common.actionSuccessful")}
            </Alert>
          )}
          
          <Typography>
            {confirmText}
          </Typography>
        </DialogContent>
        <DialogActions>
          <Button onClick={closeConfirmDialog}>
            {t("common.cancel")}
          </Button>
          <CardButton 
            actionType={type}
            cardId={cardId}
            isDefault={isDefault}
            hasMultipleCards={hasMultipleCards}
            variant="contained"
            disabled={isActionDisabled}
            label={buttonText}
            onStateChange={handleActionStateChange}
          />
        </DialogActions>
      </Dialog>
    );
  };

  // If not expanded, just show the button
  if (!dialogOpen) {
    const buttonProps = {
      view: {
        title: title || t("paymentMethods.title"),
        description: description || t("paymentMethods.pageDescription"),
        buttonText: buttonText || t("paymentMethods.viewPaymentMethods")
      },
      remove: {
        title: title || t("cardActions.removeCard"),
        description: description || t("cardActions.removeCardDescription"),
        buttonText: buttonText || t("cardActions.showCardDetails")
      },
      setDefault: {
        title: title || t("cardActions.setDefaultCard"),
        description: description || t("cardActions.setDefaultCardDescription"),
        buttonText: buttonText || t("cardActions.showCardDetails")
      }
    };

    const currentProps = buttonProps[actionType] || buttonProps.view;

    // If simpleButton is true, render just the button without wrappers
    if (simpleButton) {
      return (
        <Button
          variant="contained"
          color="primary"
          size="large"
          onClick={openDialog}
        >
          {currentProps.buttonText}
        </Button>
      );
    }

    return (
      <Box textAlign="center" py={4}>
        <Typography variant="h5" component="h2" gutterBottom>
          {currentProps.title}
        </Typography>
        
        {currentProps.description && (
          <Typography paragraph>
            {currentProps.description}
          </Typography>
        )}
        
        <Box mt={3}>
          <Button
            variant="contained"
            color="primary"
            size="large"
            onClick={openDialog}
          >
            {currentProps.buttonText}
          </Button>
        </Box>
      </Box>
    );
  }

  // Render cards with CSS-based sliding transitions (no Slide component)
  const renderCardContent = () => {
    if (!cards.length) return null;
    
    return (
      <Box sx={{ 
        position: 'relative', 
        overflow: 'hidden', 
        height: '240px',  // Fixed height to prevent jumping
        mb: 2
      }}>
        {cards.map((card, index) => {
          const isDefault = isDefaultCard(card.id);
          
          return (
            <Box
              key={card.id}
              sx={{
                position: 'absolute',
                top: 0,
                left: 0,
                width: '100%',
                transition: 'transform 300ms ease, opacity 300ms ease',
                transform: `translateX(${(index - activeCardIndex) * 100}%)`,
                opacity: index === activeCardIndex ? 1 : 0,
                visibility: Math.abs(index - activeCardIndex) <= 1 ? 'visible' : 'hidden', // Only render nearby cards
                zIndex: index === activeCardIndex ? 2 : 1,
              }}
            >
              <Card variant="outlined">
                <CardContent>
                  <Typography variant="h6">
                    {card.card.brand} •••• {card.card.last4}
                  </Typography>
                  
                  <Typography variant="body2" color="text.secondary" sx={{ mt: 1 }}>
                    {t("paymentMethods.expires")} {card.card.exp_month}/{card.card.exp_year}
                  </Typography>
                  
                  {isDefault && (
                    <Typography variant="body2" color="primary.main" sx={{ mt: 1 }}>
                      {t("paymentMethods.defaultCard")}
                    </Typography>
                  )}
                  
                  <Divider sx={{ my: 2 }} />
                  
                  <Grid container spacing={1}>
                    {!isDefault && (
                      <Grid item xs={6}>
                        <Button
                          variant="outlined" 
                          size="small"
                          fullWidth
                          onClick={() => openConfirmDialog('setDefault', card.id)}
                        >
                          {t("cardActions.setDefault")}
                        </Button>
                      </Grid>
                    )}
                    
                    <Grid item xs={isDefault ? 12 : 6}>
                      <Button
                        variant="outlined"
                        color="error"
                        size="small"
                        fullWidth
                        onClick={() => openConfirmDialog('remove', card.id)}
                        disabled={isDefault && !hasMultipleCards}
                      >
                        {t("cardActions.remove")}
                      </Button>
                    </Grid>
                  </Grid>
                </CardContent>
              </Card>
            </Box>
          );
        })}
      </Box>
    );
  };
  
  // Render add card button
  const renderAddCard = () => {
    if (!showAddCardButton) return null;
    
    return (
      <Card variant="outlined" sx={{ mt: 2 }}>
        <CardContent sx={{ 
          display: 'flex', 
          flexDirection: 'row',
          justifyContent: 'space-between',
          alignItems: 'center'
        }}>
          <Typography>
            {t("paymentMethods.addNewCard")}
          </Typography>
          
          <Button
            variant="contained"
            onClick={() => window.location.href = '/card/add'}
            startIcon={<AddIcon />}
          >
            {t("paymentMethods.addCard")}
          </Button>
        </CardContent>
      </Card>
    );
  };

  // Main dialog content
  const renderMainDialog = () => {
    // Render loading state
    if (isLoading) {
      return (
        <Box display="flex" justifyContent="center" alignItems="center" p={4}>
          <CircularProgress />
        </Box>
      );
    }
    
    // Render error state
    if (hasError) {
      return (
        <Alert severity="error" sx={{ m: 2 }}>
          {t("common.errorLoadingData")}
        </Alert>
      );
    }
    
    // No cards found
    if (cards.length === 0) {
      return (
        <Box textAlign="center" p={3}>
          <Typography variant="h6" gutterBottom>
            {t("paymentMethods.noCards")}
          </Typography>
          
          {showAddCardButton && (
            <Box mt={2}>
              <Button
                variant="contained"
                onClick={() => window.location.href = '/card/add'}
                startIcon={<AddIcon />}
              >
                {t("paymentMethods.addFirstCard")}
              </Button>
            </Box>
          )}
        </Box>
      );
    }
    
    // Has cards
    return (
      <>
        <Box sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center', mb: 2 }}>
          {cards.length > 1 && (
            <IconButton 
              onClick={prevCard} 
              size="small" 
              aria-label="Previous card"
            >
              <KeyboardArrowLeftIcon />
            </IconButton>
          )}
          
          <Typography variant="body2" sx={{ mx: 2 }}>
            {t("paymentMethods.cardCount", { current: activeCardIndex + 1, total: cards.length })}
          </Typography>
          
          {cards.length > 1 && (
            <IconButton 
              onClick={nextCard} 
              size="small" 
              aria-label="Next card"
            >
              <KeyboardArrowRightIcon />
            </IconButton>
          )}
        </Box>
        
        {actionState && actionState.success && (
          <Alert severity="success" sx={{ mb: 2 }}>
            {actionState.result?.message || t("common.actionSuccessful")}
          </Alert>
        )}
        
        {actionState && actionState.error && (
          <Alert severity="error" sx={{ mb: 2 }}>
            {actionState.error.message || t("common.actionFailed")}
          </Alert>
        )}
        
        {renderCardContent()}
        
        {renderAddCard()}
      </>
    );
  };

  return (
    <>
      {/* Initial button to open dialog */}
      {!dialogOpen && (
        // This section is only rendered if simpleButton is false (handled above)
        <Box textAlign="center" py={4}>
          <Typography variant="h5" component="h2" gutterBottom>
            {title || t("paymentMethods.title")}
          </Typography>
          
          {description && (
            <Typography paragraph>
              {description}
            </Typography>
          )}
          
          <Box mt={3}>
            <Button
              variant="contained"
              color="primary"
              size="large"
              onClick={openDialog}
            >
              {buttonText || (actionType === 'view' 
                ? t("paymentMethods.viewPaymentMethods") 
                : t("cardActions.showCardDetails"))}
            </Button>
          </Box>
        </Box>
      )}
      
      {/* Main Dialog with Cards */}
      <Dialog
        open={dialogOpen}
        onClose={closeDialog}
        fullWidth
        maxWidth="sm"
        TransitionComponent={DialogTransition}
      >
        <DialogTitle>
          {title || t("paymentMethods.title")}
          <IconButton
            aria-label="close"
            onClick={closeDialog}
            sx={{
              position: 'absolute',
              right: 8,
              top: 8,
            }}
          >
            <CloseIcon />
          </IconButton>
        </DialogTitle>
        <DialogContent>
          {renderMainDialog()}
        </DialogContent>
        <DialogActions>
          <Button onClick={closeDialog}>
            {t("common.close")}
          </Button>
        </DialogActions>
      </Dialog>
      
      {/* Confirmation Dialog */}
      {renderConfirmDialog()}
    </>
  );
};

export default PaymentMethodsUserInterface;